<!--
* @author luguoxiang
* @date 2021-09-07
* 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
-->
<template>
  <slot :options="options">
    <component :is="props.component || 't-select'" :options="options" v-bind="$attrs" />
  </slot>
</template>

<script lang="ts" setup>
import { Component as ComponentDef, ref, watchEffect } from 'vue';
import { LgDictProps } from '../types';
import { getDict, toNumberArray } from '@/soar';

/**
 * 获取数据
 * @param data
 */
function getDataArray(data) {
  if (typeof data === 'function') {
    data = data();
  }
  if (Array.isArray(data)) {
    return data;
  }
  return [data];
}

interface Props extends LgDictProps {
  /**
   * 字典code
   */
  code: string;
  /**
   * 隐藏的值
   */
  hiddenValue?: number | number[] | string;
  /**
   * 禁用的值
   */
  disabledValue?: number | number[] | string;
  /**
   * 数据处理器
   */
  handler?: Function;
  /**
   * 前面的选项
   */
  prepend?: Function | Object[] | Object;
  /**
   * 后面的选项
   */
  append?: Function | Object[] | Object;
  /**
   * 使用的组件(可以是组件引入对象或字符串（全局引入的）)
   */
  component?: ComponentDef | string;
}
const props = defineProps<Props>();
const options = ref([]);
// 加载数据
watchEffect(() => {
  if (!props.code) {
    return;
  }
  getDict(props.code).then((res) => {
    if (props.handler) {
      options.value = props.handler(res);
    } else {
      const hiddenValue = toNumberArray(props.hiddenValue ?? []);
      const disabledValue = toNumberArray(props.disabledValue ?? []);
      let list = [];
      for (const x of res) {
        if (hiddenValue.includes(x.value)) {
          continue;
        }
        list.push({
          value: x.value,
          label: x.label,
          disabled: disabledValue.includes(x.value),
        });
      }
      if (props.prepend) {
        list = getDataArray(props.prepend).concat(list);
      }
      if (props.append) {
        list = list.concat(getDataArray(props.append));
      }
      options.value = list;
    }
  });
});
</script>
<script lang="ts">
export default {
  name: 'LgDict',
};
</script>
